package cn.iocoder.yudao.module.written.exam.service.jobcategories;

import cn.iocoder.yudao.module.written.exam.controller.admin.jobcategories.vo.JobCategoriesPageReqVO;
import cn.iocoder.yudao.module.written.exam.controller.admin.jobcategories.vo.JobCategoriesSaveReqVO;
import cn.iocoder.yudao.module.written.exam.controller.admin.jobcategories.vo.JobCategoriesTreeReqVO;
import cn.iocoder.yudao.module.written.exam.controller.admin.jobcategories.vo.JobCategoriesTreeRespVO;
import cn.iocoder.yudao.module.written.exam.dal.dataobject.jobcategories.JobCategoriesDO;
import cn.iocoder.yudao.module.written.exam.dal.mysql.jobcategories.JobCategoriesMapper;
import cn.iocoder.yudao.module.written.exam.enums.EnableStatusEnum;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;


import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.written.exam.enums.ErrorCodeConstants.JOB_CATEGORIES_NOT_EXISTS;

/**
 * 职位分类 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class JobCategoriesServiceImpl implements JobCategoriesService {

    @Resource
    private JobCategoriesMapper jobCategoriesMapper;

    @Override
    public Long createJobCategories(JobCategoriesSaveReqVO createReqVO) {
        // 插入
        JobCategoriesDO jobCategories = BeanUtils.toBean(createReqVO, JobCategoriesDO.class);
        jobCategoriesMapper.insert(jobCategories);
        // 返回
        return jobCategories.getId();
    }

    @Override
    public void updateJobCategories(JobCategoriesSaveReqVO updateReqVO) {
        // 校验存在
        validateJobCategoriesExists(updateReqVO.getId());
        // 更新
        JobCategoriesDO updateObj = BeanUtils.toBean(updateReqVO, JobCategoriesDO.class);
        jobCategoriesMapper.updateById(updateObj);
    }

    @Override
    public void deleteJobCategories(Long id) {
        // 校验存在
        validateJobCategoriesExists(id);
        // 删除
        jobCategoriesMapper.deleteById(id);
    }

    private void validateJobCategoriesExists(Long id) {
        if (jobCategoriesMapper.selectById(id) == null) {
            throw exception(JOB_CATEGORIES_NOT_EXISTS);
        }
    }

    @Override
    public JobCategoriesDO getJobCategories(Long id) {
        if (Objects.isNull(id)) {
            return null;
        }
        return jobCategoriesMapper.selectById(id);
    }

    @Override
    public JobCategoriesDO getJobCategoriesByName(String name) {
        LambdaQueryWrapper<JobCategoriesDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(JobCategoriesDO::getCategoryName, name);
        return jobCategoriesMapper.selectOne(lambdaQueryWrapper);
    }

    @Override
    public PageResult<JobCategoriesDO> getJobCategoriesPage(JobCategoriesPageReqVO pageReqVO) {
        return jobCategoriesMapper.selectPage(pageReqVO);
    }

    private List<JobCategoriesTreeRespVO> getChildren(Long parentCategoryId, Map<Long, List<JobCategoriesTreeRespVO>> jobCategoriesIdAndjobCategoriesInfoTreeMap) {
        List<JobCategoriesTreeRespVO> jobCategoriesTreeRespVOList = jobCategoriesIdAndjobCategoriesInfoTreeMap.get(parentCategoryId);
        if (CollectionUtils.isEmpty(jobCategoriesTreeRespVOList)) {
            return new ArrayList<>();
        }
        return jobCategoriesTreeRespVOList.stream()
                .filter(item -> Objects.equals(item.getParentCategoryId(), parentCategoryId))
                .peek(item -> {
                            List<JobCategoriesTreeRespVO> children = getChildren(item.getId(), jobCategoriesIdAndjobCategoriesInfoTreeMap);
                            item.setChildren(children);
                        }
                ).collect(Collectors.toList());
    }

    @Override
    public List<JobCategoriesTreeRespVO> queryJobCategoriesTree(JobCategoriesTreeReqVO treeReqVO) {
        LambdaQueryWrapper<JobCategoriesDO> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(JobCategoriesDO::getEnableStatus, EnableStatusEnum.ENABLE.getCode());
        List<JobCategoriesDO> jobCategoriesDOList = jobCategoriesMapper.selectList(lambdaQueryWrapper);

        if (CollectionUtils.isEmpty(jobCategoriesDOList)) {
            return new ArrayList<>();
        }

        List<JobCategoriesTreeRespVO> jobCategoriesTreeRespVOList = jobCategoriesDOList.stream().map(item -> {
            JobCategoriesTreeRespVO jobCategoriesTreeRespVO = new JobCategoriesTreeRespVO();
            BeanUtils.copyProperties(item, jobCategoriesTreeRespVO);
            return jobCategoriesTreeRespVO;
        }).collect(Collectors.toList());

        Map<Long, List<JobCategoriesTreeRespVO>> jobCategoriesIdAndjobCategoriesInfoTreeMap = new HashMap<>();
        jobCategoriesTreeRespVOList.forEach(item -> {
            jobCategoriesIdAndjobCategoriesInfoTreeMap.computeIfAbsent(item.getParentCategoryId(), k -> new ArrayList<>()).add(item);
        });

        return getChildren(0L, jobCategoriesIdAndjobCategoriesInfoTreeMap);
    }

}